﻿using CoreApp.Utility;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CoreApp.Web.Core
{
    /// <summary>
    /// XSS攻击防御过滤器
    /// </summary>
    public class XSSFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            //获取参数集合
            var paramList = context.ActionDescriptor.Parameters;
            //遍历参数集合
            foreach (var param in paramList)
            {
                var name = param.Name;
                var isContainsKey = context.ActionArguments.ContainsKey(name);
                if (isContainsKey && context.ActionArguments[name] != null)
                {
                    var paramType = param.ParameterType;
                    //当参数是str
                    if (paramType.Equals(typeof(string)))
                    {
                        //过滤后对参数重新赋值
                        context.ActionArguments[name] = XSSHelper.XSSFilter(context.ActionArguments[name].ToString());
                    }
                    //当参数是一个实体
                    else if (paramType.IsClass)
                    {
                        EntityParamFilter(paramType, context.ActionArguments[name]);
                    }
                }
            }
        }

        /// <summary>
        /// 遍历过滤实体的属性值
        /// </summary>
        /// <param name="type">数据类型</param>
        /// <param name="obj">对象</param>
        /// <returns></returns>
        private object EntityParamFilter(Type type, object obj)
        {
            if (obj != null)
            {
                foreach (var item in type.GetProperties())
                {
                    if (item.GetValue(obj) != null)
                    {
                        var itemType = item.PropertyType;
                        //当参数是str
                        if (itemType.Equals(typeof(string)))
                        {
                            var value = item.GetValue(obj).ToString();
                            item.SetValue(obj, XSSHelper.XSSFilter(value));//过滤后对参数重新赋值
                        }
                        //当参数是一个实体
                        else if (itemType.IsClass)
                        {
                            //递归
                            item.SetValue(obj, EntityParamFilter(itemType, item.GetValue(obj)));
                        }
                    }
                }
            }
            return obj;
        }
    }
}
